第 5 章  ·  RAG核心原理(一)-工作流程与语义搜索

第5章 第2节 RAG核心原理(一)-工作流程与语义搜索


第5章 第2节 RAG核心原理(一)-工作流程与语义搜索


阅读指南

在上一节中,我们看到了RAG如何让"死"的知识库变成"活"的智能助手。但你可能会好奇:这背后到底是怎么实现的?AI是如何从成千上万份文档中,精准找到相关内容,并生成自然流畅的回答的?

这一节,我们就来揭开RAG的技术面纱。


2.1 RAG的工作流程

先从宏观角度,看看RAG完整的工作流程。

假设你的公司有一个智能FAQ系统,员工问:"我入职2年了,下周想请5天年假,来得及吗?"系统需要经历以下5个步骤:

完整流程概览

+-----------------+
|  用户提问        + "我入职2年了,下周想请5天年假,来得及吗?"
+-----------------+
        |
        v
+--------------------------------------------+
|  步骤1:问题向量化                          +
|  将问题转换成数字向量                        
|  "年假申请" -> [0.23, 0.45, 0.12, ...]      
+--------------------------------------------+
        |
        v
+--------------------------------------------+
|  步骤2:检索相关文档                        +
|  在向量数据库中搜索最相似的文档              
|  找到:年假天数、申请流程、申请限制          
+--------------------------------------------+
        |
        v
+--------------------------------------------+
|  步骤3:提取相关片段                        +
|  从检索到的文档中提取最相关的段落            
|  保留:入职年限对应天数、提前申请天数        
+--------------------------------------------+
        |
        v
+--------------------------------------------+
|  步骤4:拼接上下文                          +
|  将提取的片段和用户问题组合成Prompt          
|  参考资料:[检索到的内容]                    
|  用户问题:[原始问题]                        
+--------------------------------------------+
        |
        v
+--------------------------------------------+
|  步骤5:AI生成回答                          +
|  大模型基于上下文生成个性化回答              
|  "可以的,来得及!您入职2年,有7天..."      
+--------------------------------------------+
        |
        v
+-----------------+
|  返回给用户      +
+-----------------+

这5个步骤环环相扣,缺一不可。接下来,逐个深入理解每个步骤。


2.2 从文字到数字:Embedding的魔法

传统数据库查询时使用特定的SQL来进行查询的。之所以能查询出来是因为数据库的数据通常是“结构化”的。你看MySQL的数据是不是一张张结构规整的表?所以对于SQL查询能从数据库里查出数据来,我们一点都不吃惊。

但RAG不一样,RAG要查询的不是结构化的数据库,而是他也不知道是什么的一堆堆文字,比如一部小说、一堆网页资料等。那他是怎么查询出相关内容的?这非常值得我们探讨一番。

RAG使用的是一种“向量化”的方案,通俗的说就是把文字变成数字

为什么需要向量化

假设,要在一家图书馆找一本关于"人工智能"的书。传统方法是什么?

但这两种方法都有问题:

更聪明的方法是:给每本书一个"特征码",这个码能代表书的主题、内容、风格。比如:

《人工智能基础》     → [0.9, 0.8, 0.1, 0.2, ...]
《机器学习实战》     → [0.85, 0.75, 0.15, 0.25, ...]
《唐诗三百首》       → [0.1, 0.05, 0.9, 0.85, ...]

这样,当你问"有没有关于AI的书"时:

  1. 先把"AI"也转成特征码:[0.88, 0.82, 0.08, 0.18, ...]
  2. 计算它和每本书特征码的相似度
  3. 相似度高的就是你要找的书

这就是Embedding(嵌入)的核心思想:把文字转换成向量(一组数字),让相似的概念在数字空间里也彼此接近

Embedding的直观理解

假设我们用2维向量来表示一些词(实际上,不同的Embedding模型维度不同,但为了便于理解,我们用2维来演示):

         维度1: 动物性(0-1)
                ^
          1.0   |    "猫"(0.9, 0.8)
                |      o  "狗"(0.85, 0.75)
                |        o
          0.5   |                      "苹果"(0.1, 0.2)
                |                          o
                |                        o "橙子"(0.05, 0.15)
          0.0   +---------------------------------> 维度2: 食物性(0-1)
                0.0         0.5          1.0

可以发现:

这就是向量化的魔法:语义相近的词,在向量空间里也相互靠近。

真实的Embedding长什么样

还记得流程图中的步骤1:问题向量化吗? 看起来好像很难。

但在实际的RAG系统中,这一步通常是通过调用Embedding API来完成的。大多数模型都提供有将文字进行Embedding的API,比如Qwen就有。无论是用户的问题,还是知识库中的文档,都可以经过这个API转换成向量。

实际调用Embedding API会得到:

# 文本:"年假怎么申请"
embedding_vector = [
    0.0234, -0.0123, 0.0456, 0.0789, -0.0321, 0.0654, 
    -0.0198, 0.0432, ... (共1536个数字。不同的模型长度不一样)
]

这1536个数字,编码了"年假""申请"这些词的语义信息。

虽然我们人眼看不懂这些数字的含义,但计算机可以通过比较两个向量,判断它们的相似程度——语义相近的文本,向量在数学空间里也会彼此靠近。


2.3 相似度计算:找到最相关的内容

有了向量,下一个问题是:怎么判断两个向量"相似"?

余弦相似度

最常用的方法是余弦相似度(Cosine Similarity)。

不用担心数学公式,我们用一个直观的例子来理解:

想象两人站在原点,各自朝不同方向走:

                   北
                   ^
                   | 朋友
                   | /
                   |/
         西 <------+------> 东
                 / |
               /   |
             你    v
                   南

假设用户提问:"我怎么申请年假?"

Tip

重要说明
Embedding模型不是只能编码单个词,而是可以对整个句子、段落甚至文档进行编码。"我怎么申请年假?"这7个字会被作为一个整体,编码成一个向量。

# 步骤1:将用户的完整问题转换为向量
question = "我怎么申请年假?"  # 完整的句子
question_vector = embedding_model.encode(question)
# 结果: [0.23, 0.45, 0.12, ..., 0.33]  (1536维)

# 步骤2:知识库里的文档也都提前转换好了向量
doc1 = "年假申请流程:登录OA系统 → 选择请假申请 → 填写年假类型..."
doc1_vector = [0.25, 0.48, 0.10, ..., 0.35]  # 与问题很接近

doc2 = "公司Wi-Fi密码:办公区密码是Office2024,访客区..."
doc2_vector = [0.01, 0.02, 0.85, ..., 0.90]  # 与问题相差很远

# 步骤3:计算相似度
cosine_similarity(question_vector, doc1_vector)  # → 0.95(非常相似!)
cosine_similarity(question_vector, doc2_vector)  # → 0.12(不相关)

为什么文档1相似度高

为什么文档2相似度低

系统会优先选择相似度高的文档(如文档1),作为回答问题的参考资料。


2.4 检索阶段:在海量文档中找到答案

现在我们知道了如何计算相似度。但如果公司有10万份文档,总不能把每一份都和用户问题比较一遍吧?那太慢了!

所以,单纯的只是把文字转成向量还不行,还需要向量数据库索引技术,来解决大量向量的管理和查询问题。

向量数据库的作用

普通数据库擅长精确匹配:

SELECT * FROM documents WHERE title = '年假申请流程'

但RAG需要的是相似度搜索

找出和"年假怎么申请"最相似的5份文档

向量数据库就是为这个需求设计的:

  1. 离线阶段
    • 将所有文档转换成向量
    • 建立特殊的索引结构(如HNSW图)
    • 存储向量和原始文档的对应关系
  2. 查询阶段
    • 接收用户问题的向量
    • 利用索引快速定位最相似的候选文档
    • 返回Top-K个最相关的结果

速度对比

这差不多快了1000倍。

Top-K

RAG系统通常会取Top-3或Top-5个最相关的文档。

为什么不是Top-1或Top-10?

经验规则

具体数值需要根据实际效果调优。

2.5 ■ 学点英语

中文 English 音标 说明
语义搜索 Semantic Search /sɪˈmæntɪk sɜːrtʃ/ 基于向量空间距离衡量文本语义相似度的搜索方式
余弦相似度 Cosine Similarity /ˈkoʊsaɪn ˌsɪməˈlærəti/ 衡量两个向量方向夹角的相似度指标,范围[-1,1]
向量化 Vectorization /ˌvektərɪˈzeɪʃn/ 将文本转换成数字向量表示的过程
欧几里得距离 Euclidean Distance /juːˈklɪdiən ˈdɪstəns/ 多维空间中两点之间的直线距离
Top-K 检索 Top-K Retrieval /tɑːp keɪ rɪˈtriːvl/ 返回相似度最高的前K个检索结果

2.6 ■ 思考帧

为什么需要RAG RAG核心原理(二)-检索生成与关键机制
本节目录